#include "TcpConnectionPool.h"

// 初始化连接池
TcpConnectionPool::TcpConnectionPool(int pool_size){
    for (size_t i = 0; i < pool_size; ++i){
        connection_pool.emplace_back(std::make_shared<TCPConnection>());
    }
}

// 从连接池中获取连接
std::shared_ptr<TCPConnection> TcpConnectionPool::getConnectionFromPool(std::string server_ip, uint16_t server_port)
{
    std::lock_guard<std::mutex> lock(pool_mtx);
    for (auto conn : connection_pool) {
        std::lock_guard<std::mutex> conn_lock(conn->mtx);
        if(conn->in_connect && !conn->in_use) {
            if(conn->server_addr.sin_addr.s_addr == inet_addr(server_ip.c_str()) && conn->server_addr.sin_port == htons(server_port)) {
                conn->in_use = true;
                return conn;
            }
        }
        if (!conn->in_connect && !conn->in_use) {
            conn->sockfd = socket(AF_INET, SOCK_STREAM, 0);
            conn->server_addr.sin_family = AF_INET;
            conn->server_addr.sin_addr.s_addr = inet_addr(server_ip.c_str());
            conn->server_addr.sin_port = htons(server_port);
            if (connect(conn->sockfd, (struct sockaddr*)&conn->server_addr, sizeof(conn->server_addr)) < 0) {
                perror("连接失败");
                continue;
            }
            conn->in_connect = true;
            conn->in_use = true;
            return conn;
        }
    }
    for(auto& conn : connection_pool) {
        std::lock_guard<std::mutex> conn_lock(conn->mtx);
        if (conn->in_connect && !conn->in_use) {
            close(conn->sockfd);
            conn->sockfd = socket(AF_INET, SOCK_STREAM, 0);
            conn->server_addr.sin_family = AF_INET;
            conn->server_addr.sin_addr.s_addr = inet_addr(server_ip.c_str());
            conn->server_addr.sin_port = htons(server_port);
            if (connect(conn->sockfd, (struct sockaddr*)&conn->server_addr, sizeof(conn->server_addr)) < 0) {
                perror("连接失败");
                continue;
            }
            conn->in_connect = true;
            conn->in_use = true;
            return conn;
        }
    }
    return nullptr; // 没有可用连接
}

// 释放连接到连接池
void TcpConnectionPool::releaseConnection(std::shared_ptr<TCPConnection> conn)
{
    std::lock_guard<std::mutex> lock(conn->mtx);
    conn->in_use = false;
    // 可以选择在释放连接时关闭套接字
    // close(conn->sockfd);
}

// 关闭连接池
TcpConnectionPool::~TcpConnectionPool()
{
    for (auto& conn : connection_pool) {
        close(conn->sockfd);
        conn->in_connect = false;
        conn->in_use = false;
    }
}
